<template>
	<div>
		<!--  编辑弹框-->
		<el-dialog v-if="dialogVisible" :model-value="dialogVisible" :show-close="false" :before-close="handleClose" width="70%">
			<template #header="{ titleId, titleClass }">
				<div class="my-header">
					<h4 :id="titleId" :class="titleClass">{{ headerTitle }}</h4>
					<el-button type="danger" plain size="small" :icon="CircleCloseFilled" @click="handleClose"> 关闭弹框 </el-button>
				</div>
			</template>
			<el-form ref="ruleFormRef" :model="form" :rules="rules" label-width="120px" class="ruleForm" :size="formSize" status-icon>
				<el-form-item label="名称" prop="name">
					<el-input v-model="form.name" />
				</el-form-item>

				<el-form-item label="图片" prop="img">
					<el-upload action="" :before-upload="uploadimg" :show-file-list="true">
						<el-button type="primary" size="small">点击上传</el-button>
					</el-upload>
				</el-form-item>

				<el-form-item label="所属分类" prop="aid">
					<el-select v-model="form.aid">
						<el-option v-for="(item, index) in npcTypeList" :key="index.toString()" :label="item.name" :value="item.id"></el-option>
					</el-select>
				</el-form-item>

				<el-form-item label="所在地点" prop="address">
					<el-input v-model="form.address" type="textarea" />
				</el-form-item>

				<el-form-item label="影神图" prop="imgs">
					<el-upload
						v-model:file-list="imgListimgs"
						class="upload-demo"
						action="http://localhost:9090/api/file/upload"
						:on-preview="handlePreviewimgs"
						:on-remove="handleRemoveimgs"
						:on-success="handleSucessimgs"
						list-type="picture"
					>
						<el-button type="primary">点击上传</el-button>
						<template #tip>
							<div class="el-upload__tip"></div>
						</template>
					</el-upload>
				</el-form-item>
				<el-form-item label="详情" prop="content">
					<TiptapEditor v-model="form.content" class="editor-container" style="min-height: 500px" />
				</el-form-item>
			</el-form>
			<template #footer>
				<span class="dialog-footer">
					<el-button @click="handleResetForm(ruleFormRef)">取消</el-button>
					<el-button type="primary" @click="handleSubmitForm(ruleFormRef)"> 提交 </el-button>
				</span>
			</template>
		</el-dialog>

		<el-row style="width: 80%; position: relative; top: 60px; margin: 0 auto">
			<!--  分页查询表单按钮-->
			<el-col>
				<el-form :inline="true" style="display: flex; justify-content: center">
					<el-row>
						<el-col>
							<el-form-item label-width="5px">
								<el-input v-model="name" placeholder="输入名称" clearable @clear="load" />
							</el-form-item>
							<el-form-item label-width="5px">
								<el-button type="primary" :icon="Search" @click="load"></el-button>
							</el-form-item>
						</el-col>
					</el-row>
				</el-form>
			</el-col>
			<!-- 新增和批量按钮 -->
			<el-col :span="4">
				<el-menu
					:default-active="cid"
					class="transparent-menu"
					:unique-opened="true"
					style="width: 100%; background: transparent"
					@select="changeCateogory"
				>
					<el-menu-item key="0" index="0">
						<span style="font-size: 16px; font-weight: 500">全部类型</span>
					</el-menu-item>
					<el-menu-item v-for="(item, index) in npcTypeList" :key="item.id" :index="item.id" class="menu-item-custom">
						<el-avatar
							:src="item.img"
							:size="30"
							style="border: 2px solid #f0f2f5; border-radius: 6px; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08)"
						></el-avatar>
						<span style="margin-left: 12px; font-size: 16px; color: white"> {{ item.name }} </span>
					</el-menu-item>
				</el-menu>
			</el-col>

			<!--  表格页面-->
			<el-col :span="20">
				<div class="card-container">
					<el-row :gutter="20">
						<el-col v-for="item in tableData" :key="item.id" :span="12">
							<el-card class="card-item" shadow="hover" @click="handleDetail(item.id)">
								<el-image style="width: 100%; height: 200px; border-radius: 5px" :src="item.img" fit="contain" />
								<div class="card-content">
									<h3 class="card-title">
										{{ item.name }}
									</h3>
									<p class="card-description">{{ item.address }}</p>
								</div>
							</el-card>
						</el-col>
					</el-row>
				</div>
				<!--      分页按钮-->
			</el-col>

			<el-col>
				<div class="pagination">
					<el-pagination
						:current-page="pageNum"
						:page-size="pageSize"
						:page-sizes="[10, 20, 30, 50, 100, 500, 1000]"
						size="small"
						layout="total, sizes, prev, pager, next, jumper"
						:total="Number(total)"
						@size-change="handleSizeChange"
						@current-change="handleCurrentChange"
					/>
				</div>
			</el-col>
		</el-row>
	</div>
</template>

<script setup>
import { onBeforeUnmount, reactive, ref, shallowRef } from 'vue'
import { CircleCloseFilled, Delete, Download, Edit, InfoFilled, Plus, Refresh, Search, Upload } from '@element-plus/icons-vue'
import request from '@/utils/request'
import { ElMessage, ElMessageBox } from 'element-plus'
import downloadExcel from '@/utils/downloads'
import 'md-editor-v3/lib/style.css'
import router from '@/router'
import TiptapEditor from '@/components/tiptap/TiptapEditor.vue'

const $route = router
const headerTitle = ref()
const pageNum = ref(1)
const pageSize = ref(10)
const total = ref(0)
const tableData = ref([])
const multipleSelection = ref([])
const disabled = ref(true)
const dialogVisible = ref(false)
const npcTypeList = ref([])
const name = ref('')
const aid = ref('')
const imgListimgs = ref([])
const cid = ref('0')

const form = reactive({
	id: undefined,
	name: undefined,
	img: undefined,
	aid: undefined,
	address: undefined,
	imgs: undefined,
	content: undefined
})

//删除
const handleRemoveimgs = (uploadFile, uploadFiles) => {
	console.log(uploadFile, uploadFiles)
}
//预览
const handlePreviewimgs = file => {
	console.log(file)
}
//上传成功
const handleSucessimgs = res => {
	imgListimgs.value[imgListimgs.value.length - 1].url = res.data
}

// 表单样式
const formSize = ref('default')
// 表单ref标识数据
const ruleFormRef = ref()
// 自定义校验规则

// 表单校验规则
const rules = reactive({
	name: [{ required: true, message: '必选项不能为空', trigger: 'blur' }],
	img: [{ required: true, message: '必选项不能为空', trigger: 'change' }],
	aid: [{ required: true, message: '必选项不能为空', trigger: 'change' }],
	address: [{ required: true, message: '必选项不能为空', trigger: 'blur' }],
	imgs: [{ required: true, message: '必选项不能为空', trigger: 'change' }],
	content: [{ required: true, message: '必选项不能为空', trigger: 'blur' }]
})

//新增方法
const handleAdd = async () => {
	headerTitle.value = reactive('新增数据')
	dialogVisible.value = true
}
// 修改方法
const handleUpdate = async id => {
	dialogVisible.value = true
	headerTitle.value = reactive('编辑数据')
	const res = await request.get(`/npc/${id}`)
	Object.assign(form, res.data)

	//响应式数组
	imgListimgs.value = JSON.parse(form.imgs)
}
// 单个删除方法
const handleDel = async id => {
	await request.delete(`/npc/${id}`)
	ElMessage({
		showClose: true,
		message: '删除成功',
		type: 'success'
	})
	await load()
}
// 批量删除方法
const handleBatchDel = async () => {
	const ids = []
	multipleSelection.value.forEach(row => {
		ids.push(row.id)
	})
	await request.delete(`/npc/batch/${ids}`)
	ElMessage({
		showClose: true,
		message: '批量删除成功',
		type: 'success'
	})
	await load()
}

// 分页查询方法（初始化方法，页面加载成功以后就调用的方法）
const load = async () => {
	const res = await request.get('/npc/page', {
		params: {
			pageNum: pageNum.value,
			pageSize: pageSize.value,
			name: name.value,
			aid: aid.value
		}
	})
	pageNum.value = res.data.current
	pageSize.value = res.data.size
	total.value = res.data.total
	tableData.value = res.data.records
	//   npcTypeList
	const resnpcType = await request.get(`/npc/type`)
	npcTypeList.value = resnpcType.data
}
// 加载页面初始化调用load方法
load()

// 清空查询数据重置方法
const handleReset = () => {
	name.value = ''
	aid.value = ''
	load()
}
// 修改每页展示的数据量方法
const handleSizeChange = size => {
	pageSize.value = size
	load()
}
// 翻页方法
const handleCurrentChange = current => {
	pageNum.value = current
	load()
}
// 多选按钮处理方法
const handleSelectionChange = val => {
	multipleSelection.value = val
	disabled.value = val.length === 0
}

// 关闭弹框提示方法
const handleClose = done => {
	ElMessageBox.confirm('确定关闭窗口?')
		.then(() => {
			handleResetForm(ruleFormRef.value)
		})
		.then(() => {
			done()
		})
		.catch(() => {
			// catch error
		})
}

// 提交表单校验方法
const handleSubmitForm = async formEl => {
	if (!formEl) {
		return
	}

	if (imgListimgs.value.length > 0) {
		form.imgs = JSON.stringify(imgListimgs.value)
	} else {
		form.imgs = ''
	}

	await formEl.validate(async (valid, fields) => {
		if (valid) {
			await request({
				method: form.id ? 'put' : 'post',
				url: form.id ? `/npc/${form.id}` : '/npc',
				data: form
			})
			ElMessage({
				showClose: true,
				message: '操作成功',
				type: 'success'
			})
			await handleResetForm(formEl)
		} else {
			console.log('error submit!', fields)
		}
	})
}
// 批量导入读数据写到后端数据库中
const beforeBatchUpload = async file => {
	let fd = new FormData()
	fd.append('file', file)
	await request.post('/npc/batch/upload', fd, {
		headers: {
			'Content-Type': 'multipart/form-data'
		}
	})
	ElMessage({
		showClose: true,
		message: '上传成功',
		type: 'success'
	})
	await load()
}
// 批量导出方法
const handleBatchExport = async () => {
	const ids = multipleSelection.value.map(row => row.id)
	const res = await request(
		{
			url: `/npc/batch/export/${ids}`,
			method: 'get',
			responseType: 'blob'
		} //在请求中加上这一行，特别重要
	)
	downloadExcel(res, '导出数据表')
}
// 取消弹框方法
const handleResetForm = async formEl => {
	if (!formEl) {
		return
	}
	formEl.resetFields()
	imgListimgs.value = []

	Object.assign(form, {
		id: undefined,
		name: undefined,
		img: undefined,
		aid: undefined,
		address: undefined,
		imgs: undefined,
		content: undefined
	})
	// formEl.clearValidate("img")
	dialogVisible.value = false
	await load()
}

// 文件上传方法
const uploadimg = async file => {
	let fd = new FormData()
	fd.append('file', file)
	const res = await request.post('/file/upload', fd, {
		headers: {
			'Content-Type': 'multipart/form-data'
		}
	})
	ElMessage({
		showClose: true,
		message: '上传成功',
		type: 'success'
	})
	form.img = res.data
	ruleFormRef.value.clearValidate('img')
}

// 文件下载
const dowload = async url => {
	window.open(url)
}
// 富文本文件上传
const onUploadImg = async (files, callback) => {
	let i = 0
	const res = await Promise.all(
		files.map(file => {
			if (i > 0) {
				return false
			}
			return new Promise((rev, rej) => {
				const formdata = new FormData()
				formdata.append('file', file)

				request
					.post('/file/upload', formdata, {
						headers: {
							'Content-Type': 'multipart/form-data'
						}
					})
					.then(res => {
						i++
						rev(res.data)
					})
					.catch(error => rej(error))
			})
		})
	)
	callback(res)
}

const changeCateogory = async index => {
	aid.value = index === '0' ? '' : index
	await load()
}

const handleDetail = async id => {
	$route.push(`/front/npc/detail?id=${id}`)
}
</script>

<style scoped lang="scss">
.card-container {
	padding: 20px;
}

.card-item {
	margin-bottom: 20px;
	border-radius: 12px;
	overflow: hidden;
	transition:
		transform 0.3s cubic-bezier(0.4, 0, 0.2, 1),
		box-shadow 0.3s cubic-bezier(0.4, 0, 0.2, 1);
	cursor: pointer; /* 添加手型光标 */
	position: relative;

	&:hover {
		transform: translateY(-5px);
		box-shadow: 0 10px 20px rgba(0, 0, 0, 0.15);

		&::after {
			opacity: 0.1;
		}
	}

	&::after {
		content: '';
		position: absolute;
		top: 0;
		left: 0;
		right: 0;
		bottom: 0;
		background: linear-gradient(45deg, #409eff 0%, #79bbff 100%);
		opacity: 0;
		transition: opacity 0.3s ease;
		z-index: 1;
	}
}

.card-content {
	padding: 16px;
	position: relative;
	z-index: 2;
	background: white;
}

.card-image {
	border-radius: 8px;
	margin-bottom: 12px;
	transition: transform 0.3s ease;
}

.card-title {
	font-size: 1.25rem;
	font-weight: 600;
	margin-bottom: 8px;
	color: #1f2d3d;
	position: relative;
	padding-bottom: 8px;

	&::after {
		content: '';
		position: absolute;
		bottom: 0;
		left: 0;
		width: 40px;
		height: 2px;
		background: #409eff;
		transition: width 0.3s ease;
	}
}

.card-item:hover .card-title::after {
	width: 60px;
}

.card-description {
	font-size: 0.875rem;
	color: #5e6d82;
	line-height: 1.6;
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
	text-overflow: ellipsis;
	margin-top: 8px;
}

@keyframes cardHover {
	0% {
		transform: translateY(0);
	}
	50% {
		transform: translateY(-3px);
	}
	100% {
		transform: translateY(-5px);
	}
}

.card-meta {
	display: flex;
	align-items: center;
	margin-top: 10px;
}

.meta-text {
	font-size: 12px;
	color: #999;
	margin-left: 8px;
}

@media (max-width: 768px) {
	.card-item {
		margin-bottom: 15px;
	}

	.card-title {
		font-size: 1.1rem;
	}

	.card-description {
		font-size: 0.8rem;
	}
}

.pagination {
	position: fixed;
	bottom: 20px;
	left: 50%;
	transform: translateX(-50%);
	z-index: 1000;
	background: rgba(255, 255, 255, 0.9);
	padding: 8px 20px;
	border-radius: 24px;
	box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
	display: inline-flex;

	:deep(.el-pagination__total),
	:deep(.el-pagination__jump),
	:deep(.el-pagination__sizes),
	:deep(.btn-prev),
	:deep(.btn-next) {
		color: #333;
	}

	:deep(.el-pager li) {
		color: #333;

		&.is-active {
			color: #409eff;
		}
	}
}

.transparent-menu {
	background: transparent !important;
	border-radius: 8px;
	padding: 12px 16px;
	transition: all 0.3s ease;

	/* 优化子项样式 */
	.el-menu-item {
		height: 50px;
		line-height: 40px;
		padding: 0 12px;
		border-radius: 30px;
		transition: all 0.2s ease;

		&:hover {
			background: rgba(64, 158, 255, 0.1) !important;

			.el-avatar {
				border-color: #409eff;
				box-shadow: 0 0 8px rgba(64, 158, 255, 0.2);
			}
			&.is-active {
				.el-avatar {
					box-shadow: 0 0 12px rgba(64, 158, 255, 0.3);
				}
			}

			span {
				color: #409eff;
			}
		}
	}

	.el-menu-item.is-active {
		background: rgba(64, 158, 255, 0.6) !important;
		font-weight: 500;

		.el-avatar {
			border-color: #409eff;
			box-shadow: 0 0 4px rgba(64, 158, 255, 0.3);
		}

		span {
			color: #000000;
		}
	}
}

/* 优化头像和文字间距 */
.menu-item-custom {
	display: flex;
	align-items: center;
	gap: 8px;
	font-size: 14px;
	color: #666;
	transition: all 0.2s ease;
}
</style>
